package com.health.viewscontrols.medical.device.fm;

import android.bluetooth.BluetoothGatt;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.blankj.utilcode.util.ClickUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.SpanUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.callback.BleWriteCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.scan.BleScanRuleConfig;
import com.clj.fastble.utils.HexUtil;
import com.health.R;
import com.health.httpbean.model.FmModel;
import com.health.httpbean.model.WaistBean;
import com.health.tablebean.SBCL_DATA_NEW;
import com.health.viewscontrols.NovaApplication;
import com.health.viewscontrols.medical.base.BaseDeviceActivity;
import com.novabluetooth.data.DeviceShowSaveData;
import com.peng.ppscalelibrary.BleManager.Model.LFPeopleGeneral;

import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * DH 身高体重秤
 */
public class DhFMActivity extends BaseDeviceActivity {

    public final static UUID UUID_SERVICE =
            UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb");
    public final static UUID UUID_WRITE =
            UUID.fromString("0000ffe2-0000-1000-8000-00805f9b34fb");
    public final static UUID UUID_NOTIFY =
            UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb");
    private BleDevice mBleDevice;

    @Override
    public void doBusiness() {
//        et_height.setVisibility(View.VISIBLE);
//        tv_state.setText(com.nova.health.ble.R.string.fm_qj_tip);
        tv_operation_tips.setText(com.nova.health.ble.R.string.fm_qj);

        BleManager.getInstance().init(getApplication());
        BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
                .setDeviceMac(deviceEnum.getMac())
                .setScanTimeOut(10000)
                .build();
        BleManager.getInstance().initScanRule(scanRuleConfig);
    }

    @Override
    public void startDevice() { int height = 0;
        scanBle();
    }

    @Override
    public void update(String hexStr) {

    }

    @Override
    public void disconnectDevice() {
        try {
            mBleDevice = null;
            BleManager.getInstance().cancelScan();
            BleManager.getInstance().disconnectAllDevice();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void scanBle() {
        if (mBleDevice != null) {
            if (BleManager.getInstance().isConnected(mBleDevice)) {
                Log.e(TAG, "scanBle: " );
                showDialog("正在测量身高体重");
                blueToothState.setText("连接成功");
                writeCmd(mBleDevice,"10$");
                writeCmd(mBleDevice, "11$");
                return;
            }
        }

        try {
            BleManager.getInstance().disconnectAllDevice();
        } catch (Exception e) {
            e.printStackTrace();
        }
        showDialog("正在连接身高体重秤");
        BleManager.getInstance().scan(new BleScanCallback() {
            @Override
            public void onScanStarted(boolean success) {
            }

            @Override
            public void onScanning(BleDevice bleDevice) {
                Log.e(TAG, "onScanning:2222 " + bleDevice.getName() );
                if (!TextUtils.isEmpty(bleDevice.getName())) {
//                    if (bleDevice.getName().startsWith("DHHW")) {
//                    if(bleDevice.getName().startsWith("DH")&&!bleDevice.getName().startsWith("DHBF")){
//                        BleManager.getInstance().cancelScan();
//                        connectionBle(bleDevice);
//                    }
                    if (bleDevice != null && deviceEnum.getMac().equals(bleDevice.getMac())) {
                        BleManager.getInstance().cancelScan();
                        connectionBle(bleDevice);
                    }
                }
            }

            @Override
            public void onScanFinished(List<BleDevice> scanResultList) {

            }
        });
    }

    private void connectionBle(BleDevice bleDevice) {
        BleManager.getInstance().connect(bleDevice, new BleGattCallback() {
            @Override
            public void onStartConnect() {
                blueToothState.setText("正在连接设备...");
            }

            @Override
            public void onConnectFail(BleDevice bleDevice, BleException exception) {
                blueToothState.setText("连接失败");
                Log.e(TAG, "onConnectFail: " +  exception.toString());
            }

            @Override
            public void onConnectSuccess(final BleDevice bleDevice, BluetoothGatt gatt, int status) {
                //连接成功
                Log.e(TAG, "onConnectSuccess: " + bleDevice.getMac() );
                LogUtils.file("已连接：" + bleDevice.getMac() +  gatt.toString());
                Log.e(TAG, "onConnectSuccess: 连接成功" );
                blueToothState.setText("连接成功");
                if (stringBuilder != null) {
                    stringBuilder.delete(0, stringBuilder.length());
                }
                mBleDevice = bleDevice;
                showDialog("正在测量身高体重");
                getNotify(bleDevice);
                writeCmd(bleDevice,"10$");
                writeCmd(bleDevice, "11$");
            }

            @Override
            public void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status) {
                blueToothState.setText("已断开连接");
                LogUtils.file("已断开连接：" + device.getMac() +  gatt.toString());
            }
        });
    }

    private void writeCmd(final BleDevice bleDevice, String cmd) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                writeData(bleDevice,cmd);
            }
        },400);
    }

    StringBuilder stringBuilder = new StringBuilder();
    private void getNotify(final BleDevice bleDevice) {
        BleManager.getInstance().notify(bleDevice,
                UUID_SERVICE.toString(),
                UUID_NOTIFY.toString(),
                new BleNotifyCallback() {
                    @Override
                    public void onNotifySuccess() {
                        Log.e(TAG, "onNotifySuccess: " );
                    }

                    @Override
                    public void onNotifyFailure(BleException exception) {
                        Log.e(TAG, "onNotifyFailure: " +exception.toString());
                    }

                    @Override
                    public void onCharacteristicChanged(byte[] data) {
                        try {
                            final String tmpValue = new String(data, StandardCharsets.UTF_8);
                            Log.e(TAG, "接收到的原始数据: " + HexUtil.formatHexString(data));
                            Log.e(TAG, "接收到的解析数据: " + tmpValue );
                            Log.e(TAG, "stringBuilder原始数据: " + stringBuilder.toString() );
                            if ("60$".equals(tmpValue)) {
//                                showLog("接收到的数据：设备在线 " + tmpValue);
                            } else if ("11$".equals(tmpValue)){
//                                showLog("接收到的数据：正在启动设备测量数据 " + tmpValue);
                            } else {
                                stringBuilder.append(HexUtil.formatHexString(data));
                                Log.e(TAG, "接收到的解析数据: " + tmpValue );
                                Log.e(TAG, "stringBuilder拼接数据: " + stringBuilder.toString() );
                                if (stringBuilder.toString().contains("0d0a")) {
                                    final String tmpValue1 = new String(
                                            HexUtil.hexStringToBytes(stringBuilder.toString()),
                                            StandardCharsets.UTF_8);
                                    Log.e(TAG, "stringBuilder解析数据: " + tmpValue1);

                                    parseResult(tmpValue1);
                                    stringBuilder.delete(0, stringBuilder.length());
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
    }

    /**
     * 写入数据
     * @param bleDevice
     * @param data
     */
    private void writeData(BleDevice bleDevice, final String data) {
        byte[] bytes = hexStringToBytes(strTo16(data));
        Log.e(TAG, "writeData: " + bytes);
        BleManager.getInstance().write(
                bleDevice,
                UUID_SERVICE.toString(),
                UUID_WRITE.toString(),
                bytes, new BleWriteCallback() {
                    @Override
                    public void onWriteSuccess(int current, int total, byte[] justWrite) {
                        LogUtils.file("写入数据成功：" + data);
                    }

                    @Override
                    public void onWriteFailure(BleException exception) {
                        ToastUtils.showShort("测量失败" + exception.toString());
                        Log.e(TAG, "onWriteFailure: " + exception.toString() );
                    }
                });
    }

    private void parseResult(String paramString) {
        try {
            if (paramString.contains("W:") && paramString.contains("H:")) {
                String[] arrayOfString = paramString.substring(paramString.indexOf("W:") + "W:".length()).split("H:");
                if (arrayOfString != null && arrayOfString.length == 2)
                    try {
                        double weight = Double.parseDouble(arrayOfString[0].trim());
                        double height = Double.parseDouble(arrayOfString[1].trim());
                        double bmi = calBMI(weight, height);
                        showHealthScale(weight,height, bmi);
                        ToastUtils.showLong("测量成功!");

                        cancelProgressDialog();
                        return;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 保存轻加体脂秤测量结果
     */
    private void showHealthScale(double weight, double height, double bmi) {
        LFPeopleGeneral lfPeopleGeneral = new LFPeopleGeneral();
        lfPeopleGeneral.lfWeightKg = weight;
        lfPeopleGeneral.lfHeightCm = height;
        lfPeopleGeneral.setLfBMI(bmi);
        Log.e(TAG, "showHealthScale: "+ lfPeopleGeneral.toString() );

        tv_result.setText("测量结果：\n  身高:" + height + "cm；体重：" + weight + "kg，bmi：" + bmi);
        tv_state.setText("获取测量结果成功");
        FmModel fmModel = new FmModel();
        fmModel.setHeight(height + "");
        fmModel.setWeight(weight + "");
        fmModel.setBmi(bmi + "");

        //保存体重
        DeviceShowSaveData.saveHealthScale(lfPeopleGeneral, weight + "");
        DeviceShowSaveData.saveCLData(
                "鼎恒身高体重秤",
                "鼎恒身高体重秤",
                "身高",
                height + "",
                "身高",
                UUID.randomUUID().toString(),
                NovaApplication.getUserInfo().getIDCARD(),
                TimeUtils.date2String(new Date(),"yyyy-MM-dd HH:mm:ss")
        );
        DeviceShowSaveData.saveCLData(
                "鼎恒身高体重秤",
                "鼎恒身高体重秤",
                "体质指数",
                weight+"(体重)/"+height+"²(身高的平方)="+bmi+"(体质指数)",
                "体质指数",
                UUID.randomUUID().toString(),
                NovaApplication.getUserInfo().getIDCARD(),
                TimeUtils.date2String(new Date(),"yyyy-MM-dd HH:mm:ss")
        );
        DeviceShowSaveData.getDataShow(GsonUtils.toJson(fmModel), "FM2");
        DeviceShowSaveData.saveTizhong(GsonUtils.toJson(fmModel));
    }

    private void showDialog(String title) {
        runOnUiThread(() -> {
            showProgressDialog(title);
        });
    }

    public static String strTo16(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            int ch = s.charAt(i);
            String s4 = Integer.toHexString(ch);
            str = str + s4;
        }
        return str;
    }

    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.trim();
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    public static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    public double calBMI(double weight, double height) {
        DecimalFormat df = new DecimalFormat("#.00");
        double newheight = height / 100;
        double v = weight / (newheight * newheight);
        String format = df.format(v);
        return Double.parseDouble(format);
    }

}
